// Copyright (c) 2011 The Kiwii Authors. All rights reserved.
// Use of this source code is governed by the New BSD License that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "KiwiiClient-internal.hxx"
#include "net/Networking.hxx"
#include "comm/Protocol.hxx"
#include "comm/Exception.hxx"
#include "comm/Logger.hxx"
#include "backend/Operation.hxx"
#include <netinet/in.h>
#include <sys/socket.h>
#include <cerrno>

namespace kiwii {

  using namespace kiwii::net;
  using comm::Exception;
  using comm::Logger;
  using namespace comm::protocol;

  static Logger& logger = Logger::get();

  KClientImpl::KClientImpl(int connfd, net::EventLoopBase& el, KServer& server) : KClient(connfd, el), server_(server) {
    struct sockaddr_storage addr;
    auto len = sizeof(addr);
    if (getpeername(connfd, (struct sockaddr*)&addr, &len) < 0) {
      throw Exception("getpeername():") << boost::errinfo_errno(errno);
    }

    convertBinaryAddressToString((struct sockaddr*)&addr, addr_, port_);

    logger.info("client connection established from %s:%d", addr_.c_str(), port_);
  }

  void KClientImpl::onRequest(comm::protocol::Request const& req) {
    auto op = OperationFactory::instance().get(req.arg(0)); // The first argument of the request is the operation name.
    auto reply = op(db_, req);
    sendReply(reply.toString());
  }

}
